;**********************************************************************
;   This file is the source code for the PIC Tuner Control which      *
;   interfaces the Icom IC-706MkIIg with the SGC model SG-237         *
;   tuner.                                                            *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:	    TCI-1V37.asm                                       *
;    Date:         07/23/2003                                         *
;    File Version: 3.7                                                *
;                                                                     *
;    Author:  Robert W. Lewis                                         *
;    Company: Intelligent Software Solutions                          *
;                                                                     * 
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files required:                                                  *
;       p16c505.inc                                                   *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;       Clock Frequency = 32.000 kHz                                  *
;       This firmware will function on Version 2.x PC Board           *
;       Option jumper settings (A - B):                               *
;           00 - IC706MkIIg & SG-237                                  *
;           01 - unused                                               *
;           10 - unused                                               *
;           11 - unused                                               *
;                                                                     *
;       Osc startup is too slow to catch to STRT pulse which can be   *
;       as narrow as 50mS. We'll assume that if we get to STARTUP     *
;       it was as a result of the STRT pulse since this is the only   *
;       input to PORT B which has wake on pin change.                 *
;                                                                     *
;       This version unlocks the tuner during power-up to avoid       *
;       an SG-237 problem of disabling tune from memory if it is      *
;       powered up with the lock switch closed. A version 3.3 PC      *
;       board is also required to implement this function.            *
;                                                                     *
;       All ports go to inputs on wake-up so tuner is always          *
;       unlocked by the pull-up resistor until the TRIS has been set. *
;                                                                     *
;**********************************************************************

	list      p=16c505            ; list directive to define processor
	#include <p16c505.inc>        ; processor specific variable definitions

	__CONFIG   _CP_OFF & _WDT_OFF & _MCLRE_OFF & _LP_OSC

;***** VARIABLE DEFINITIONS
;The Ports
TUNED    EQU      0x000 ; Port RC0 - input
LOCK     EQU      0x001 ; Port RC1 - output
RST      EQU      0x002 ; Port RC2 - output
TKEY     EQU      0x004 ; Port RC4 - output
STRT     EQU      0x001 ; Port RB1 - input

; Setup for the option register
;	Wake-up on pin change = enabled  (bit-7 = 0)
;	Weak pull-ups = disabled         (bit-6 = 1)
;	Timer0 source = internal clock   (bit-5 = 0)
;	Timer0 edge select = low to high (bit-4 = 0)
;	Prescaler assigned to Timer0     (bit-3 = 0)
;	Prescaler rate = 1:8             (bits-2..0 = 010)
OPTIONSET   EQU   0x42 ; 01000010 Binary

; Setup for TRIS registers
;  Port B never needs to be changed since it defaults
;     to all inputs (1)
;  Port C change RC-1, RC2, and RC-4 to outputs
TRISCSET    EQU   0x0E9 ; 11101001 binary

; Registers
TIMEMS      EQU   0x009 ; Storage for mS delay value
TIMESEC     EQU   0x00A ; Storage for Sec delay value
MSTRT       EQU   0x00B ; Storage for old STRT status
DLYFLG      EQU   0x00C ; Storage for delay request flag

;**********************************************************************
         ORG      0x3FF             ; processor reset vector

         ORG      0x000             ; coding begins here
         clrf     FSR               ; ensure FSR register points to Bank0
         movlw    OPTIONSET         ; Set the option register
         option
         btfsc    STATUS, RBWUF     ; Wake from sleep?
         goto     STARTUP           ; Yes

; No, then it was Power On Reset, Begin Processor Initialization
         clrf     PORTB             ; All output latches = 0
         clrf     PORTC             ; All output latches = 0
         bsf      PORTC, LOCK       ; Unlock the tuner
         movlw    TRISCSET          ; Set direction registers
         tris     PORTC
         movlw    0x00F             ; Set the
         movwf    DLYFLG            ;   delay request flag
  
DONE     bcf      PORTC, TKEY       ; Unkey the TX
         movlw    .100              ; Delay 100mS
         btfsc    DLYFLG, 1         ;  only if delay
         call     DELAY             ;    request flag is set
         clrf     DLYFLG            ; Clear the flag
         bcf      PORTC, LOCK       ; Enable lock switch
CHKSTRT  btfsc    PORTB, STRT       ; Wait here until
         goto     CHKSTRT           ;   STRT becomes inactive. 
         sleep                      ; Sleep til next STRT

STARTUP  bsf      PORTC, LOCK       ; Unlock the tuner
         movlw    TRISCSET          ; Set direction registers
         tris     PORTC
         clrf     DLYFLG            ; Clear the delay request flag
         call     BYPASS            ; Put tuner in bypass
         clrf     TMR0              ; Reset the timer
STRLOOP  btfss    PORTB, STRT       ; Still start?
         goto     DONE              ; No - only tuner reset requested
         movlw    .190              ; Yes, if TMR0 = 190mS then
         xorwf    TMR0, 0           ;   set the zero bit.
         btfss    STATUS, Z         ; Zero bit set?
         goto     STRLOOP           ; No, loop again
         movlw    0x00F             ; Yes, Tune Requested,
         movwf    MSTRT             ;    flag STRT as active.
         clrf     DLYFLG            ; Clear the delay request flag
         bsf      PORTC, TKEY       ; Key the Tx
         movlw    .120              ; Set up 30 sec timer
         movwf    TIMESEC
         movlw    .250              ; Set up 1/4-sec timer
         movwf    TIMEMS
SECLOOP  clrf     TMR0              ; Reset the 1/4-sec timer
MSLOOP   movf     TIMEMS, 0
         xorwf    TMR0, 0           ; If TMR0 = TIMEms then ZERO is set
         btfss    STATUS, Z         ; ZEROBIT Set?
         goto     CHKTUNED          ; No
         decfsz   TIMESEC, 1        ; Dec sec counter - 30 sec yet?
         goto     SECLOOP           ; No
         goto     TIMEOUT           ; Yes
CHKTUNED btfss    PORTC, TUNED      ; Are we tuned yet?
         goto     CANCEL            ; No
TIMEOUT  bcf      PORTC, TKEY       ; Yes - Clear Tx key
         movlw    .20               ; Delay 20 mS
         call     DELAY
         btfsc    PORTC, TUNED      ; Are we tuned?
         goto     DONE              ; Yes
         bsf      PORTC, TKEY       ; Failed tune - signal the radio
         movlw    .200              ; Delay 200 mS
         call     DELAY
         goto     DONE
CANCEL   btfsc    PORTB, STRT       ; Start active?
         goto     CANCEL1           ; Yes
         clrf     MSTRT             ; No, clear flag
         goto     MSLOOP            ; Continue
CANCEL1  btfsc    MSTRT, STRT       ; Even been inactive?
         goto     MSLOOP            ; No, continue
         bcf      PORTC, TKEY       ; Yes, unkey the TX
         call     BYPASS            ; Put tuner in bypass mode
         goto     DONE              ; Finish up

; Sub-Routines

; Place tuner in bypass mode.
BYPASS   btfss    PORTC, TUNED      ; Are we tuned?
         goto     BYPASS1           ; No, then skip the reset
         bsf      PORTC, RST        ; Yes, pulse the RST line
         movlw    0x00F             ; Set the
         movwf    DLYFLG            ;   delay request flag
BYPASS1  movlw    .40               ; No, wait 40mS
         call     DELAY
         bcf      PORTC, RST        ; Clear the RST line
         retlw    1

; Delay timer. Call with W = delay in mS
DELAY    movwf    TIMEMS            ; Get the delay time (mS)
         clrf     TMR0              ; Reset the timer
DELAYLP  movf     TIMEMS, 0
         xorwf    TMR0, 0           ; If TMR0 = TIMEms then zero is set
         btfss    STATUS, Z         ; ZERO BIT set?
         goto     DELAYLP           ; No
         retlw    1                 ; Yes

         END                        ; directive 'end of program'

